package com.lz.autotest.project.testmanage.autoTest.service.thread;

import com.alibaba.fastjson2.JSON;
import com.lz.autotest.common.constant.ListenerTypeConstants;
import com.lz.autotest.common.constant.ReportStatusConstants;
import com.lz.autotest.common.utils.DateUtils;
import com.lz.autotest.project.testmanage.autoTest.entity.ResultView;
import com.lz.autotest.project.testmanage.autoTest.entity.TsstAutotestMenu;
import com.lz.autotest.project.testmanage.autoTest.service.Listener.Listener;
import com.lz.autotest.project.testmanage.autoTest.service.Listener.Observable;
import com.lz.autotest.project.testmanage.infmanage.domain.SstInf;
import com.lz.autotest.project.testmanage.reportmanage.domain.SstReportItem;
import com.lz.autotest.project.testmanage.infmanage.service.impl.InfServiceImpl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author: X
 * @date: Created in 2023/6/21 14:24
 * @Description: 执行任务的线程
 */
public class AutoTestXtsThreadByLog extends Thread implements Observable {

    private volatile boolean isRunning = true;

    private String threadName;

    private List<SstInf> sstInfs;

    private List<List<String>> list;

    private List<Listener> listeners;

    private TsstAutotestMenu tsstAutotestMenu;

    private String responseIp;

    public AutoTestXtsThreadByLog(String threadName, List<SstInf> sstInfs, List<List<String>> list, List<Listener> listeners, TsstAutotestMenu tsstAutotestMenu ) {
        this.threadName = threadName;
        this.sstInfs = sstInfs;
        this.list = list;
        this.listeners = listeners;
        this.tsstAutotestMenu = tsstAutotestMenu;
        this.responseIp = tsstAutotestMenu.getRequestIp();
    }

    private InfServiceImpl service = new InfServiceImpl();

    @Override
    public void run() {
        // 执行线程的逻辑
        SstReportItem report = buildSstInfReport(tsstAutotestMenu);
        String reportId = tsstAutotestMenu.getReportId();
        Long start = System.currentTimeMillis();
        String allConsumerTime = "";
        Long max = 0L;
        Long min = 10000L;
        //根据日志进行请求
        for (List<String> reqs : list) {
            for (int i = 0; i < sstInfs.size(); i++) {
                SstInf sstInf = sstInfs.get(i);
                sstInf.setInfRequest(reqs.get(i));
                //线程中断处理
                while (Thread.currentThread().isInterrupted()) {
                    return;
                }
                ResultView resultView = service.requestServeByAutoTest(sstInf);
                HashMap<String, Object> sendData = new HashMap<>();
                sendData.put("reportId", reportId);
                sendData.put("result", resultView);
                notifySendDataListener(sendData);
                max = max < resultView.getConsumeTime() ? resultView.getConsumeTime() : max;
                min = min > resultView.getConsumeTime() ? resultView.getConsumeTime() : min;
                if (allConsumerTime.equals("")) {
                    allConsumerTime += resultView.getConsumeTime();
                } else {
                    allConsumerTime = allConsumerTime + "," + resultView.getConsumeTime();
                }
                report.setConsumeTime(resultView.getConsumeTime() + report.getConsumeTime());
                if (resultView.decideByStatus()) {
                    report.setSuccessCount(report.getSuccessCount() + 1);
                } else {
                    report.setFailCount(report.getFailCount() + 1);
                }
            }
        }
        Long end = System.currentTimeMillis();
        report.setAvgConsumeTime(report.getConsumeTime() / (list.size() * sstInfs.size()));
        report.setMaxConsumeTime(max);
        report.setMinConsumeTime(min);
        report.setStatus(ReportStatusConstants.DONE);
        report.setConsumeTime(end - start);
        report.setAllConsumeTime(allConsumerTime);
        report.setEndTime(DateUtils.getCurr_YYYY_MM_DD_HH_MM_SS());

        if (tsstAutotestMenu.isMcs()) {
            HashMap<String, Object> calcInfo = new HashMap<>();
            calcInfo.put("msg", report);
            notifyCalcServerListener(calcInfo);
        }
        HashMap<String, Object> downData = new HashMap<>();
        downData.put("ip", responseIp);
        downData.put("msg", report);
        notifyDownloadDataListener(downData);
        return;
    }

    public void stopRunning() {
        isRunning = false;
    }

    @Override
    public void registerListener(Listener listener) {
        listeners.add(listener);
    }

    @Override
    public void removeListener(Listener listener) {
        listeners.remove(listener);
    }

    public void notifySendDataListener(Map<String, Object> map) {
        for (Listener listener : listeners) {
            if (listener.getListenerType().equals(ListenerTypeConstants.SEND_DATA)) {
                listener.execute(map);
            }
        }
    }

    public void notifyDownloadDataListener(Map<String, Object> map) {
        for (Listener listener : listeners) {
            if (listener.getListenerType().equals(ListenerTypeConstants.DOWNLOAD_DATA)) {
                listener.execute(map);
            }
        }
    }

    public void notifyCalcServerListener(Map<String, Object> map) {
        for (Listener listener : listeners) {
            if (listener.getListenerType().equals(ListenerTypeConstants.CALC_SERVER_DATA)) {
                listener.execute(map);
            }
        }
    }

    public SstReportItem buildSstInfReport(TsstAutotestMenu tsstAutotestMenu) {
        SstReportItem report = new SstReportItem();
        report.setReportId(tsstAutotestMenu.getReportId());
        report.setMenuId(tsstAutotestMenu.getMenuId());
        report.setStartTime(tsstAutotestMenu.getCalcTime());
        report.setCalcDate(DateUtils.getCurr_YYYY_MM_DD());
        report.setCreateBy(tsstAutotestMenu.getCreateBy());
        report.setReportName(tsstAutotestMenu.getMenuName());
        report.setInfEnv(tsstAutotestMenu.getRunEnv());
        report.setConcurrency(tsstAutotestMenu.getThreadNumber());
        report.setRound((int) tsstAutotestMenu.getCycleNumber());
        report.setCount(list.size() * sstInfs.size());
        report.setAllInfInfo(JSON.toJSONString(sstInfs));
        report.setRequestTime(tsstAutotestMenu.getCalcTime());
        return report;
    }
}
